﻿using PBO.Data;
using PokemonBattle.BattleNetwork;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;

namespace PBO.Game.BattleClass
{
    public partial class Battle
    {
        #region "BattleLogic"

        private void NextMove(PlayerBattleMove move)
        {
            move.SetTarget(this, _random);
            Move moveValue = default(Move);
            Pokemon pm = move.PM;
            int moveIndex = move.MoveIndex;
            List<Pokemon> targets = move.Target;

            pm.BattleState.moved = true;
            pm.BattleState.destinyBond = false;
            pm.BattleState.rage = false;
            pm.BattleState.grudge = false;

            if (pm.BattleState.nextTurnCantMove == true)
            {
                log.AppendMsg("Stiff", pm.GetNameString());
                //log.AppendText(pm.GetNameString() + "因反作用力而不能行动");
                pm.BattleState.nextTurnCantMove = false;
                return;
            }
            else
            {
                moveValue = GetPokemonMove(move);
                if (moveValue == null)
                    return;
            }

            if (!CanMove(pm, moveValue, moveIndex))
            {
                if (pm.BattleState.Hide || pm.BattleState.prepare)
                    Prepare(moveValue, pm);
                return;
            }
            if (!Prepare(moveValue, pm))
                return;
            UseSkill(pm, moveValue, targets, false);
        }

        private Move GetPokemonMove(PlayerBattleMove move)
        {
            Move nextMove;
            Pokemon pM = move.PM;
            int moveIndex = move.MoveIndex;
            if ((pM.BattleState.CrazyAttack || pM.BattleState.Hide) || pM.BattleState.prepare)
            {
                return pM.BattleState.nextMove;
            }
            if (pM.BattleState.bide)
            {
                if (pM.BattleState.bideCounter == 1)
                {
                    return null;
                }
                nextMove = pM.BattleState.nextMove;
                pM.BattleState.nextMove = null;
                return nextMove;
            }
            if (move.Struggle)
            {
                //绝境反击
                return new Move(165, null, 0);
            }
            if (!pM.BattleState.encore)
            {
                return pM.GetSelMove(moveIndex);
            }
            nextMove = pM.GetSelMove(pM.lastMoveIndex);
            if (nextMove.Target != pM.GetSelMove(moveIndex).Target)
            {
                TargetIndex defaultTarget = TargetIndex.DefaultTarget;
                switch (nextMove.Target)
                {
                    case MoveTarget.选一:
                    case MoveTarget.任选:
                    case MoveTarget.随机:
                        defaultTarget = TargetIndex.Random;
                        break;
                    case MoveTarget.自身:
                        defaultTarget = TargetIndex.Self;
                        break;
                    case MoveTarget.队友:
                        defaultTarget = TargetIndex.TeamFriend;
                        break;
                }
                move.Target.Clear();
                move.Target.AddRange(this.GetTargetsFromIndex(pM, nextMove, defaultTarget));
            }
            return nextMove;
        }

        /// <summary>
        /// 技能是否使用成功
        /// </summary>
        private bool UseSkillSuccessed(Move move, Pokemon user, IEnumerable<Pokemon> targets, bool moveCalled)
        {
            bool failed = MoveFail(move, user, targets);
            if (!user.BattleState.bide)
            {
                if (!moveCalled)
                {
                    if (!object.ReferenceEquals(user.BattleState.nextMove, move))
                    {
                        move.Used();
                        if ((move.AttackAtTarget || move.Target == MoveTarget.敌场 || move.Target == MoveTarget.全场 || move.Data.AddEffect2 == MoveAdditionalEffect.二回合后伤害) && move.PP > 0)
                        {
                            if (move.Target == MoveTarget.敌场 || move.Target == MoveTarget.全场)
                                targets = user.MyTeam.Group.Opponent.SelectedPokemon;
                            foreach (Pokemon target in targets)
                            {
                                if (target.GetSelTrait() == Trait.Pressure && target.HealthPower != 0)
                                {
                                    move.Used(); break; // TODO: might not be correct. Was : Exit For
                                }
                            }
                        }
                        if (move.Data.Id == 165)
                        {
                            //绝境反击
                            user.lastMoveIndex = StruggleIndex;
                        }
                        else
                        {
                            byte index = 1;
                            foreach (var m in user.GetSelMoves())
                            {
                                if (m.Data.Id == move.Data.Id)
                                {
                                    user.lastMoveIndex = index;
                                    break;
                                }
                                index++;
                            }
                        }
                    }
                    if (user.ChoiceItem)
                        user.UsedItem = user.GetItem();
                }

                log.AppendMsg("UseMove", user.GetNameString(), move.Data.Name);
                //log.AddText(user.GetNameString() + "使用了" + move.Name + "！");

                if (move.Data.AddEffect2 == MoveAdditionalEffect.震级)
                {
                    //double rand = _random.NextDouble();
                    int r = _random.Next(7);
                    int power = r * 20 + 10;
                    if (r == 6) power += 20;
                    log.AppendMsg("Magnitude", r + 4);
                    //log.AddText("震级" + (r + 4) + "！");
                    move.SetPower(power);
                }
            }
            if (failed) { Fail(); return false; }
            return true;
        }

        private bool CanMove(Pokemon pm, Move move, int index)
        {
            if (pm.State == PokemonState.Sleep)
            {
                if (pm.sleepCounter == pm.sleepTurn)
                {
                    log.AppendMsg("DeSLP", pm.GetNameString());
                    //this.log.AddText(pm.GetNameString() + "醒了过来！");
                    pm.State = PokemonState.No;
                }
                else
                {
                    Pokemon pokemon = pm;
                    pokemon.sleepCounter++;
                    log.AppendMsg("SLP", pm.GetNameString());
                    //this.log.AddText(pm.GetNameString() + "正在睡觉");
                    if ((move.Data.Effect != MoveEffect.梦话) && (move.Data.AddEffect2 != MoveAdditionalEffect.自身睡眠攻击有效))
                    {
                        return false;
                    }
                }
            }
            if ((pm.GetSelTrait(false) == Trait.Truant) && pm.BattleState.traitRaised)
            {
                log.AppendMsg("Truant", pm.GetNameString());
                //this.log.AddText(pm.GetNameString() + "正在偷懒！");
                return false;
            }
            if (pm.State == PokemonState.Freeze)
            {
                if (this.RandomHappen(75) && (move.Data.AddEffect2 != MoveAdditionalEffect.解除冻结))
                {
                    log.AppendMsg("FRZ", pm.GetNameString());
                    //this.log.AddText(pm.GetNameString() + "因冻结而不能行动");
                    return false;
                }
                pm.State = PokemonState.No;
                log.AppendMsg("DeFRZ", pm.GetNameString());
                //this.log.AddText(pm.GetNameString() + "解冻了！");
            }
            if (pm.BattleState.afraid)
            {
                log.AppendMsg("Flinch", pm.GetNameString());
                //this.log.AddText(pm.GetNameString() + "因害怕而不能行动");
                return false;
            }
            if (pm.BattleState.confusion)
            {
                if (pm.BattleState.confusionCounter == pm.BattleState.confusionTurn)
                {
                    log.AppendMsg("DeConfuse", pm.GetNameString());
                    //this.log.AddText(pm.GetNameString() + "解除了混乱！");
                    pm.BattleState.confusion = false;
                }
                else
                {
                    PokemonBattleState battleState = pm.BattleState;
                    battleState.confusionCounter++;
                    log.AppendMsg("Confuse", pm.GetNameString());
                    //this.log.AddText(pm.GetNameString() + "混乱了");
                    if (this.OneNth(2))
                    {
                        log.AppendMsg("ConfuseWork");
                        //this.log.AppendText(pm.CustomName + "攻击了自己");
                        double damageValue = ((((((((pm.LV * 0.4) + 2.0) * pm.GetAttack(false)) * 40.0) / ((double)pm.GetDefence(null, false))) * 0.02) + 2.0) * this._random.Next(0x55, 0x65)) * 0.01;
                        pm.GetHurt(damageValue);
                        return false;
                    }
                }
            }
            if (pm.BattleState.captivated)
            {
                log.AppendMsg("EnAttract", pm.GetNameString());
                //this.log.AddText(pm.GetNameString() + "着迷了");
                if (this.OneNth(2))
                {
                    log.AppendMsg("Attract", pm.CustomName, pm.BattleState.captivateTarget.GetNameString());
                    //this.log.AddText(pm.CustomName + "爱上了" + pm.BattleState.captivateTarget.GetNameString());
                    return false;
                }
            }
            if (pm.State == PokemonState.Paralysis && pm.GetSelTrait(false) != Trait.MagicGuard && this.OneNth(4))
            {
                log.AppendMsg("PARWork", pm.GetNameString());
                //this.log.AddText(pm.GetNameString() + "因麻痹而不能行动");
                return false;
            }
            if (((index != 5) && pm.CanChooseMove) && !pm.CanUseMove(index, true))
            {
                return false;
            }
            return true;
        }

        private bool Prepare(Move selMove, Pokemon user)
        {
            bool prepareCount = false;
            if (user.BattleState.prepare || user.BattleState.Hide)
                prepareCount = true;
            switch (selMove.Data.AddEffect2)
            {
                case MoveAdditionalEffect.准备后攻击:
                    if (prepareCount)
                    {
                        user.BattleState.prepare = false;
                        user.BattleState.nextMove = null;
                    }
                    else if (user.GetItem() == Item.PowerHerb)
                    {
                        user.RaiseItem();
                    }
                    else
                    {
                        user.BattleState.prepare = true;
                        user.BattleState.nextMove = selMove;
                        log.AppendMsg("Prepare" + selMove.Data.Id, user.GetNameString());
                        //log.AppendText(user.GetNameString() + "正在准备！");
                        return false;
                    }
                    break;
                case MoveAdditionalEffect.火箭头槌:
                    if (prepareCount)
                    {
                        user.BattleState.prepare = false;
                        user.BattleState.nextMove = null;
                    }
                    else if (user.GetItem() == Item.PowerHerb)
                    {
                        user.RaiseItem();
                        user.AbilityLvUpChanged(StatType.Def, 1, false);
                        //user.DefLVUp(1, false);
                    }
                    else
                    {
                        user.BattleState.prepare = true;
                        user.BattleState.nextMove = selMove;
                        log.AppendMsg("Prepare" + selMove.Data.Id, user.GetNameString());
                        //log.AppendText(user.GetNameString() + "正在准备！");
                        user.AbilityLvUpChanged(StatType.Def, 1, false);
                        //user.DefLVUp(1, false);
                        return false;
                    }
                    break;
                case MoveAdditionalEffect.太阳光线:
                    if (prepareCount)
                    {
                        user.BattleState.prepare = false;
                        user.BattleState.nextMove = null;
                    }
                    else if (Ground.Weather != Weather.Sunny)
                    {
                        if (user.GetItem() == Item.PowerHerb)
                        {
                            user.RaiseItem();
                        }
                        else
                        {
                            user.BattleState.prepare = true;
                            user.BattleState.nextMove = selMove;
                            log.AppendMsg("Prepare" + selMove.Data.Id, user.GetNameString());
                            //log.AppendText(user.GetNameString() + "正在准备！");
                            return false;
                        }
                    }
                    break;
                case MoveAdditionalEffect.潜水后攻击:
                    return user.Dive(prepareCount, selMove);
                case MoveAdditionalEffect.挖洞后攻击:
                    return user.Dig(prepareCount, selMove);
                case MoveAdditionalEffect.跳起后攻击:
                    return user.Jump(prepareCount, selMove);
                case MoveAdditionalEffect.飞天后攻击:
                    return user.Fly(prepareCount, selMove);
                case MoveAdditionalEffect.消失后攻击:
                    return user.Disappear(prepareCount, selMove);
            }
            return true;
        }

        private bool MoveFail(Move selMove, Pokemon user, IEnumerable<Pokemon> target)
        {
            bool flag = false;

            switch (selMove.Data.AddEffect2)
            {
                case MoveAdditionalEffect.保护取消:
                    if ((target != null) && !target.First().BattleState.protect)
                    {
                        flag = true;
                    }
                    break;

                case MoveAdditionalEffect.对象睡眠攻击有效:
                    if ((target != null) && (target.First().State != PokemonState.Sleep))
                    {
                        flag = true;
                    }
                    break;

                case MoveAdditionalEffect.自身睡眠攻击有效:
                    if (user.State != PokemonState.Sleep)
                    {
                        flag = true;
                    }
                    break;

                case MoveAdditionalEffect.受到伤害攻击失败:
                    if (user.turnHurt.Count > 0)
                    {
                        flag = true;
                    }
                    break;

                case MoveAdditionalEffect.呕吐:
                    if (user.BattleState.StockpileCounter == 0)
                    {
                        flag = true;
                    }
                    break;

                case MoveAdditionalEffect.二回合后伤害:
                    if ((target != null) && target.First().BattleState.futureAtk)
                    {
                        flag = true;
                    }
                    break;

                case MoveAdditionalEffect.下马威:
                    if (!user.BattleState.firstTurnAtk)
                    {
                        flag = true;
                    }
                    break;

                case MoveAdditionalEffect.自然恩惠:
                    if (!user.GetItem(true).IsBerry())
                    {
                        flag = true;
                    }
                    break;

                case MoveAdditionalEffect.其他招式用过后可使用:
                    if ((selMove == user.GetSelMove(1)) && (user.GetSelMove(2) == null))
                    {
                        flag = true;
                    }
                    else
                    {
                        if (user.GetSelMoves().Any(m => m.Data.AddEffect2 != MoveAdditionalEffect.其他招式用过后可使用 && !m.EverUsed))
                        {
                            flag = true;
                        }
                    }
                    break;

                case MoveAdditionalEffect.对手攻击技巧有效:
                    flag = true;
                    if (target != null && this.atkList.Any(m => m.PM == target.First() && m.AttackMove))
                    {
                        flag = false;
                    }
                    break;
            }
            if (selMove.Data.AddEffect1 != MoveAdditionalEffect.自爆 || (!this.Ground.Damp && user.GetSelTrait(false) != Trait.MoldBreaker))
            {
                return flag;
            }
            return true;
        }

        /// <summary>
        /// 对象是否可攻击
        /// </summary>
        private bool CanAttackTarget(Move move, Pokemon target, Pokemon user)
        {
            if (target.HealthPower == 0)
            {
                log.AppendMsg("Fail0");
                //this.log.AppendText(user.CustomName + "的技能没有对象！");
                return false;
            }
            if (target.BattleState.protect && move.Protectable)
            {
                log.AppendMsg("Protect", target.GetNameString());
                //this.log.AppendText(target.GetNameString() + "保护了自己！");
                return false;
            }
            if (((((target.BattleState.dive && move.Data.AddEffect2 != MoveAdditionalEffect.对象潜水伤害加倍 && move.Data.AddEffect2 != MoveAdditionalEffect.击中潜水对象) ||
                (target.BattleState.dig && move.Data.AddEffect2 != MoveAdditionalEffect.对象挖洞伤害加倍)) ||
                ((target.BattleState.fly || target.BattleState.jump) && ((move.Data.AddEffect2 != MoveAdditionalEffect.对象空中伤害加倍) && (move.Data.AddEffect2 != MoveAdditionalEffect.雷电)))) || target.BattleState.disappear) && ((move.AttackAtTarget && (user.GetSelTrait(false) != Trait.NoGuard)) && (target.GetSelTrait(false) != Trait.NoGuard)))
            {
                log.AppendMsg("Miss", target.GetNameString());
                //this.log.AppendText(target.GetNameString() + "不在攻击范围！");
                return false;
            }
            var type = move.Type;
            if (user.GetSelTrait(false) == Trait.Normalize)
            {
                type = user.Type1;
            }
            if ((user.GetSelTrait(false) != Trait.MoldBreaker) && move.AttackAtTarget)
            {
                if ((target.GetSelTrait(false) == Trait.WaterAbsorb) && (type == BattleType.Water))
                {
                    target.RaiseTrait();
                    return false;
                }
                if ((target.GetSelTrait(false) == Trait.DrySkin) && (type == BattleType.Water))
                {
                    target.RaiseTrait();
                    return false;
                }
                if ((target.GetSelTrait(false) == Trait.VoltAbsorb) && (type == BattleType.Electric))
                {
                    target.RaiseTrait();
                    return false;
                }
                if (((target.GetSelTrait(false) == Trait.FlashFire) && (type == BattleType.Fire)) && (target.State != PokemonState.Freeze))
                {
                    target.RaiseTrait();
                    return false;
                }
                if ((target.GetSelTrait(false) == Trait.MotorDrive) && (type == BattleType.Electric))
                {
                    target.RaiseTrait();
                    return false;
                }
                if (((target.GetSelTrait(false) == Trait.Levitate) || target.BattleState.suspension) && ((((type == BattleType.Ground) && (move.Data.Category != MoveCategory.变化)) && (!this.Ground.Gravity && (target.GetItem(false) != Item.IronBall))) && !target.BattleState.ingrain))
                {
                    log.AppendMsg("NoEffect", target.GetNameString());
                    //this.log.AppendText(target.GetNameString() + "的浮游特性使得攻击无效！");
                    return false;
                }
                if (target.GetSelTrait(false) == Trait.Soundproof && move.Sound)
                {
                    target.ShowTrait();
                    log.AppendMsg("NoEffect", target.GetNameString());
                    //this.log.AppendText(target.GetNameString() + "的隔音特性使得技能无效！");
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 计算命中
        /// </summary>
        private static double CalculateAcc(Pokemon user, Pokemon target, Move selMove)
        {
            var weather = user.MyTeam.ground.Weather;
            double acc = 1.0;
            if (selMove.Data.Accuracy == 0) return 1.0;
            //if ((selMove.Data.Category == MoveCategory.变化) && (((selMove.Target == MoveTarget.自身 || selMove.Target == MoveTarget.己场) || (selMove.Target == MoveTarget.技能 || selMove.Target == MoveTarget.全场)) || ((selMove.Target == MoveTarget.敌场 || selMove.Target == MoveTarget.全体) || (selMove.Target == MoveTarget.队友))))
            //{
            //    return 1.0;
            //}
            if ((((((selMove.Data.Accuracy <= 100) && !target.BattleState.lockOn) &&
                (selMove.Data.AddEffect2 != MoveAdditionalEffect.必中)) &&
                ((selMove.Data.AddEffect2 != MoveAdditionalEffect.雷电) || (weather != Weather.Rainy))) &&
                ((selMove.Data.AddEffect2 != MoveAdditionalEffect.暴风雪) || (weather != Weather.HailStorm))) &&
                ((!user.BattleState.pursuit && (user.GetSelTrait(false) != Trait.NoGuard)) &&
                (target.GetSelTrait(false) != Trait.NoGuard)))
            {
                if (selMove.Data.AddEffect2 == MoveAdditionalEffect.必杀)
                {
                    if (user.LV < target.LV)
                    {
                        return -1.0;
                    }
                    acc = ((double)((30 + user.LV) - target.LV)) / 100.0;
                }
                else
                {
                    acc = (double)selMove.Data.Accuracy / 100.0;
                    if ((selMove.Data.AddEffect2 == MoveAdditionalEffect.雷电) && (weather == Weather.Sunny))
                    {
                        acc = 0.5;
                    }
                    acc *= target.GetEvasion(user, false);

                    if (user.MyTeam.ground.Gravity)
                    {
                        //this.Ground.Gravity
                        acc = acc * 5 / 3;
                        //acc *= 1.6666666666666667;
                    }
                    if (selMove.Data.AddEffect2 != MoveAdditionalEffect.必杀)
                    {
                        if (((((user.GetSelTrait(false) != Trait.MoldBreaker) && (target.GetSelTrait(false) == Trait.SandVeil)) && (weather == Weather.SandStorm)) || ((target.GetSelTrait(false) == Trait.SnowCloak) && (weather == Weather.HailStorm))) || ((target.GetSelTrait(false) == Trait.TangledFeet) && target.BattleState.confusion))
                        {
                            acc *= 0.8;
                        }
                        if (user.GetSelTrait(false) == Trait.Compoundeyes)
                        {
                            acc *= 1.3;
                        }
                        if ((user.GetSelTrait(false) == Trait.Hustle) && (selMove.Data.Category == MoveCategory.物理))
                        {
                            acc *= 0.8;
                        }
                        if (user.GetItem(false) == Item.ZoomLens)
                        {
                            acc *= 1.1;
                        }
                        else if ((user.GetItem(false) == Item.WideLens) && target.BattleState.moved)
                        {
                            acc *= 1.2;
                        }
                    }
                    if (target.GetItem(false) == Item.Brightpowder)
                    {
                        acc *= 0.9;
                    }
                }
            }
            if ((selMove.Data.AddEffect2 == MoveAdditionalEffect.必杀) && (user.LV < target.LV))
            {
                return -1.0;
            }
            return acc;
        }

        private void UseSkill(Pokemon user, Move move, List<Pokemon> targets, bool moveCall)
        {
            if (this.UseSkillSuccessed(move, user, targets, moveCall))
            {
                if (targets.Count == 0)
                {
                    this.UseNoTargetSkill(user, move);
                }
                else if (targets.Count == 1)
                {
                    if ((targets[0] == user) || (move.Target == MoveTarget.队友))
                    {
                        this.UseNoTargetSkill(user, move);
                    }
                    else
                    {
                        if (((this.Ground.followPokemon != null) && (this.Ground.followPokemon.HealthPower != 0)) && (this.Ground.followPokemon != user.Friend))
                        {
                            targets[0] = this.Ground.followPokemon;
                        }
                        if (((targets[0].HealthPower == 0) && (targets[0].Friend != null)) && (targets[0].Friend != user))
                        {
                            targets[0] = targets[0].Friend;
                        }
                        if (move.Data.Category == MoveCategory.变化)
                        {
                            this.AssistTarget(move, user, targets[0], moveCall);
                        }
                        else
                        {
                            this.UseAttackSkill(move, user, targets[0], moveCall, false);
                        }
                    }
                }
                else
                {
                    targets.RemoveAll(p => p.HealthPower == 0);
                    if (targets.Count == 0)
                    {
                        log.AppendMsg("Fail0");
                        //this.log.AppendText(user.CustomName + "的技能没有对象！");
                    }
                    else
                    {
                        foreach (Pokemon pokemon in targets)
                        {
                            if (move.Data.Category == MoveCategory.变化)
                            {
                                this.AssistTarget(move, user, pokemon, moveCall);
                            }
                            else
                            {
                                this.UseAttackSkill(move, user, pokemon, moveCall, targets.Count > 1);
                            }
                        }
                    }
                }
                user.BattleState.previousMove = move.Data.Id;
                if (move.Data.Effect == MoveEffect.临别礼物)
                {
                    user.HurtFraction(1);
                }
                else if ((move.Data.AddEffect1 == MoveAdditionalEffect.自爆) && (user.HealthPower != 0))
                {
                    user.HurtFraction(1);
                }
                else if (move.Data.AddEffect2 == MoveAdditionalEffect.震级)
                {
                    move.SetPower(0x270f);
                }
                if ((((user.GetItem(false) == Item.LifeOrb) && (user.HealthPower != 0)) && (user.attackSuccessed && (user.GetSelTrait(false) != Trait.MagicGuard))) && !moveCall)
                {
                    log.AppendMsg("LifeOrb", user.GetNameString());
                    //this.log.AddText(user.GetNameString() + "因为生命玉而受到了伤害！");
                    user.HurtFraction(10);
                }
            }
        }

        private void UseNoTargetSkill(Pokemon user, Move move)
        {
            if (move.Data.Category == MoveCategory.变化)
            {
                if (user.BattleState.snatched && move.Snatchable && user.BattleState.snatchBy.HealthPower != 0)
                {
                    log.AppendMsg("Snatch", user.BattleState.snatchBy.GetNameString(), user.GetNameString());
                    //log.AppendText(user.GetNameString() + "的技能效果被" + user.BattleState.snatchBy.GetNameString() + "抢夺了！");
                    user = user.BattleState.snatchBy;
                }

                if (move.Target == MoveTarget.己场)
                {
                    AssistUserTeam(move, user.MyTeam.Group, user);
                }
                else if (move.Target == MoveTarget.敌场)
                {
                    AssistTargetTeam(move, user.MyTeam.Group.Opponent);
                }
                else if (move.Target == MoveTarget.全场)
                {
                    AssistAllCourt(move, user);
                }
                else if (move.Target == MoveTarget.技能)
                {
                    AssistMoveCall(move, user);
                }
                else if (move.Target == MoveTarget.自身 || move.Target == MoveTarget.任选)
                {
                    AssistUser(move, user);
                }
                else if (move.Target == MoveTarget.队友)
                {
                    if (user.Friend != null)
                        AssistFriend(move, user.Friend);
                }
            }
            else
            {
                Pokemon target = default(Pokemon);
                int damage = 0;
                switch (move.Data.AddEffect2)
                {
                    case MoveAdditionalEffect.金属爆破:
                        if (user.turnHurt.Count <= 0)
                        {
                            this.Fail();
                            return;
                        }
                        else
                        {
                            target = this.GetPokemonFromIndex(user.turnHurtBy[user.turnHurt.Count - 1]);
                            damage = Convert.ToInt32(Math.Truncate((double)user.turnHurt[user.turnHurt.Count - 1] * 1.5));
                            this.NoTargetAttack(move, user, target, damage);
                        }
                        break;
                    case MoveAdditionalEffect.镜返:
                        if (user.turnHurt.Count > 0)
                        {
                            for (int i = user.turnHurt.Count - 1; i >= 0; i += -1)
                            {
                                if (GameService.GetMove(user.turnHurtMove[i]).Category == MoveCategory.特殊)
                                {
                                    target = GetPokemonFromIndex(user.turnHurtBy[i]);
                                    damage = user.turnHurt[i] * 2;
                                    NoTargetAttack(move, user, target, damage);
                                    break; // TODO: might not be correct. Was : Exit For
                                }
                            }
                        }
                        else
                        {
                            Fail();
                            return;
                        }
                        break;
                    case MoveAdditionalEffect.反击:
                        if (user.turnHurt.Count > 0)
                        {
                            for (int i = user.turnHurt.Count - 1; i >= 0; i += -1)
                            {
                                if (GameService.GetMove(user.turnHurtMove[i]).Category == MoveCategory.物理)
                                {
                                    target = GetPokemonFromIndex(user.turnHurtBy[i]);
                                    damage = user.turnHurt[i] * 2;
                                    NoTargetAttack(move, user, target, damage);
                                    break; // TODO: might not be correct. Was : Exit For
                                }
                            }
                        }
                        else
                        {
                            Fail();
                            return;
                        }
                        break;
                    case MoveAdditionalEffect.克制:
                        if (!user.BattleState.bide)
                        {
                            user.BattleState.bide = true;
                            user.BattleState.bideCounter = 0;
                            user.BattleState.bideHurt = 0;
                            user.BattleState.nextMove = move;
                            return;
                        }
                        if (user.BattleState.bideHurt > 0)
                        {
                            target = GetPokemonFromIndex(user.BattleState.bideTarget);
                            damage = user.BattleState.bideHurt * 2;
                            user.BattleState.bide = false;
                            NoTargetAttack(move, user, target, damage);
                        }
                        else
                        {
                            log.AppendMsg("Fail0");
                            //log.AppendText(user.GetNameString() + "的克制失败了！");
                            return;
                        }
                        break;
                }
            }
        }

        private void NoTargetAttack(Move move, Pokemon user, Pokemon target, int damage)
        {
            if (!CanAttackTarget(move, target, user))
                return;
            var selMoveType = GetAttackMoveType(move, user);

            if (CalculateAttackTypeEffect(user, target, selMoveType) == 0)
            {
                log.AppendMsg("NoEffect", target.GetNameString());
                //log.AddText("这对" + target.GetNameString() + "没有效果...");
                return;
            }
            if (move.Data.AddEffect2 == MoveAdditionalEffect.克制)
            {
                log.AppendMsg("DeBide", user.GetNameString());
                //log.AddText(user.GetNameString() + "将受到的伤害加倍奉还！");
            }
            HurtTarget(user, target, ref damage, move, false, target.HealthPower == target.MaxHp);
            EndAttack(user, move, target);
        }

        private void UseAttackSkill(Move selMove, Pokemon user, Pokemon target, bool moveCall, bool multiTarget)
        {
            switch (selMove.Data.AddEffect2)
            {
                case MoveAdditionalEffect.保护取消:
#warning move 467
                    log.AppendMsg("Feint", target.GetNameString());
                    //this.log.AppendText(target.GetNameString() + "的保护无效了！");
                    target.BattleState.protect = false;
                    target.BattleState.protectCancel = true;
                    break;
                case MoveAdditionalEffect.二回合后伤害:
                    {
                        target.BattleState.futureAtk = true;
                        double num3 = ((double)this._random.Next(0x55, 0x65)) / 100.0;
                        double d = 1.0;
                        double num2 = 1.0;
                        if (selMove.Data.Category == MoveCategory.物理)
                        {
                            d = user.GetAttack(false);
                            num2 = target.GetDefence(target, false);
                        }
                        else
                        {
                            d = user.GetSpAttack(false);
                            num2 = target.GetSpDefence(user, false);
                        }
                        d = Math.Truncate(d);
                        num2 = Math.Truncate(num2);
                        target.BattleState.futureDamage = Convert.ToInt32(Math.Truncate((double)((((((((user.LV * 0.4) + 2.0) * d) * selMove.Power) / num2) / 50.0) + 2.0) * num3)));
                        target.BattleState.futureAtkAcc = selMove.Data.Accuracy;
                        return;
                    }
                case MoveAdditionalEffect.愤怒:
                    user.BattleState.rage = true;
                    break;
            }
            if (this.CanAttackTarget(selMove, target, user))
            {
                this.BeginAttack(selMove, user, target, moveCall, multiTarget);
                if (selMove.Data.AddEffect2 == MoveAdditionalEffect.自然恩惠)
                {
                    user.SetItem(Item.None);
                }
            }
        }

        private void AssistFriend(Move move, Pokemon pm)
        {
            switch (move.Data.Effect)
            {
                case MoveEffect.帮手:
                    pm.BattleState.assisted = true;
                    break;
            }
        }

        private void AssistAllCourt(Move selMove, Pokemon user)
        {
            switch (selMove.Data.Effect)
            {
                case MoveEffect.玩水:
                    log.AppendMsg("WaterSport");
                    //log.AddText("火属性攻击的伤害减少了！");
                    Ground.waterSport = true;
                    break;
                case MoveEffect.玩泥:
                    log.AppendMsg("MudSport");
                    //log.AddText("电属性攻击的伤害减少了！");
                    Ground.mudSport = true;
                    break;
                case MoveEffect.欺骗空间:
                    Ground.TrickRoomChange(log);
                    break;
                case MoveEffect.冰雹:
                    if (!Ground.NewWeather(Weather.HailStorm, user, log))
                    {
                        Fail();
                    }
                    break;
                case MoveEffect.放晴:
                    if (!Ground.NewWeather(Weather.Sunny, user, log))
                    {
                        Fail();
                    }
                    break;
                case MoveEffect.沙尘暴:
                    if (!Ground.NewWeather(Weather.SandStorm, user, log))
                    {
                        Fail();
                    }
                    break;
                case MoveEffect.求雨:
                    if (!Ground.NewWeather(Weather.Rainy, user, log))
                    {
                        Fail();
                    }
                    break;
                case MoveEffect.重力:
                    if (Ground.Gravity)
                    {
                        Fail();
                    }
                    else
                    {
                        Ground.Gravitate(log);
                    }
                    break;
                case MoveEffect.黑雾:
                    log.AppendMsg("Haze");
                    //log.AddText("所有能力等级恢复了原状！");

                    foreach (var pm in Group1.SelectedPokemon)
                    {
                        pm.Haze();
                    }
                    foreach (var pm in Group2.SelectedPokemon)
                    {
                        pm.Haze();
                    }

                    //foreach (Pokemon pm in team1.SelectedPokemon)
                    //{
                    //    pm.Haze();
                    //}

                    //foreach (Pokemon pm in team2.SelectedPokemon)
                    //{
                    //    pm.Haze();
                    //}

                    break;
                case MoveEffect.灭歌:
                    foreach (Pokemon pm in this.SelectedPokemons)
                    {
                        if (pm.GetSelTrait() != Trait.Soundproof)
                            pm.PerishSong();
                    }
                    log.AppendMsg("EnPerishSong");
                    //log.AddText("场上的PM听到了灭亡歌！");
                    break;
                //case MoveEffect.魔术空间:
                //    ground.MagicRoomChange(log);
                //    break;
                //case MoveEffect.神奇空间:
                //    ground.MiracleRoomChange(log);
                //    break;
            }
        }

        private void AssistTargetTeam(Move selMove, BattleGroup targetTeam)
        {
            switch (selMove.Data.Effect)
            {
                case MoveEffect.撒菱:
                    if (targetTeam.spikesCounter < 3)
                    {
                        targetTeam.spikesCounter += 1;
                    }
                    log.AppendMsg("EnSpikes", targetTeam.PlayerName);
                    //log.AddText(targetTeam.PlayerName + "的队伍被钉子包围了");
                    break;
                case MoveEffect.秘密岩石:
                    targetTeam.hideRockCounter = 1;
                    log.AppendMsg("EnStealthRock", targetTeam.PlayerName);
                    //log.AddText(targetTeam.PlayerName + "的队伍被碎石包围了");
                    break;
                case MoveEffect.毒菱:
                    if (targetTeam.poisonSpikesCounter < 2)
                    {
                        targetTeam.poisonSpikesCounter += 1;
                    }
                    log.AppendMsg("EnToxicSpikes", targetTeam.PlayerName);
                    //log.AddText(targetTeam.PlayerName + "的队伍被毒菱包围了");
                    break;
            }
        }

        private void AssistUserTeam(Move selMove, BattleGroup userTeam, Pokemon user)
        {
            switch (selMove.Data.Effect)
            {
                case MoveEffect.反射盾:
                    if (!userTeam.MakeReflect(user))
                    {
                        Fail();
                    }
                    break;
                case MoveEffect.光壁:
                    if (!userTeam.MakeLightScreen(user))
                    {
                        Fail();
                    }
                    break;
                case MoveEffect.队伍状态恢复:
                    foreach (Pokemon pm in userTeam.AlivePokemons)
                    {
                        if (!(selMove.Sound && pm.GetSelTrait() == Trait.Soundproof))
                            pm.State = PokemonState.No;
                    }
                    log.AppendMsg(selMove.Sound ? "HealBell" : "Aromatherapy");
                    //log.AppendText("全队的状态都恢复了！");
                    break;
                case MoveEffect.神秘守护:
                    if (!userTeam.MakeSafeguard())
                    {
                        Fail();
                    }
                    break;
                case MoveEffect.白雾:
                    if (!userTeam.MakeMist())
                    {
                        Fail();
                    }
                    break;
                case MoveEffect.祈福:
                    if (!userTeam.MakeLuckyChant())
                    {
                        Fail();
                    }
                    break;
                case MoveEffect.顺风:
                    if (!userTeam.MakeWithWind())
                    {
                        Fail();
                    }
                    break;
                //case MoveEffect.广域防御:
                //    if (user.BattleState.protectCounter < 6 && _random.NextDouble() < 1 / Math.Pow(2, user.BattleState.protectCounter) && userTeam.MakeWideDefence())
                //    {
                //        user.BattleState.protectCounter += 1;
                //    }
                //    else
                //    {
                //        user.BattleState.protectCounter = 0;
                //        Fail();
                //    }
                //    break;
                //case MoveEffect.快速防御:
                //    if (user.BattleState.protectCounter < 6 && _random.NextDouble() < 1 / Math.Pow(2, user.BattleState.protectCounter) && userTeam.MakeQuickDefence())
                //    {
                //        user.BattleState.protectCounter += 1;
                //    }
                //    else
                //    {
                //        user.BattleState.protectCounter = 0;
                //        Fail();
                //    }
                //    break;
            }
        }

        private void AssistMoveCall(Move selMove, Pokemon user)
        {
            switch (selMove.Data.Effect)
            {
                case MoveEffect.梦话:
                    if (user.ChoiceItem && user.BattleState.choiceSleepTalked)
                    {
                        Fail();
                        return;
                    }
                    if (user.State == PokemonState.Sleep)
                    {
                        var mh_moves = user.GetSelMoves().Where(m => m.Data.Id != selMove.Data.Id && CanSleepTalk(m)).ToArray();

                        if (mh_moves != null && mh_moves.Length > 0)
                        {
                            if (user.ChoiceItem) user.BattleState.choiceSleepTalked = true;
                            //user.BattleState.sleepTalking = true;
                            MoveCall(mh_moves[_random.Next(mh_moves.Length)], user);
                        }
                        else
                        {
                            Fail();
                            return;
                        }
                    }
                    else
                    {
                        Fail();
                    }
                    break;
                case MoveEffect.猫手:
                    var array = user.MyTeam.Group.GetAllMoveId(user).Distinct().Where(id => CanCallMove(GameService.GetMove(id))).ToArray();
                    if (array.Length == 0)
                    {
                        Fail();
                        return;
                    }
                    var msMove = new Move(array[_random.Next(array.Length)], null, 0);
                    MoveCall(msMove, user);
                    break;
                case MoveEffect.摇手指:
                    var ids = PBO.Data.SQLite.DAL.DALMoveData.GetMetronomeMoveIds();
                    int moveid = ids[_random.Next(ids.Length)];
                    var yszMove = new Move(moveid, null, 0);

                    //int MoveIndex = 0;
                    //MoveData data = default(MoveData);
                    //var moves = BattleData.GetAllMoves();
                    //do
                    //{
                    //    MoveIndex = _random.Next(0, moves.Count);
                    //    data = moves[MoveIndex];
                    //} while (!(CanCallMove(data)));
                    //yszMove = new Move(data, false);

                    MoveCall(yszMove, user);
                    break;
                case MoveEffect.效仿:
                    if (lastMoveId != 0)
                    {
                        Move move = new Move(lastMoveId, null, 0);
                        MoveCall(move, user);
                    }
                    else
                    {
                        Fail();
                    }
                    break;
                case MoveEffect.自然力量:
                    int zrllid = 0;
                    switch (Ground.Terrain)
                    {
                        case BattleTerrain.Stadium:
                            zrllid = 161;
                            break;
                        case BattleTerrain.Grass:
                            zrllid = 402;
                            break;
                        case BattleTerrain.Flat:
                            zrllid = 89;
                            break;
                        case BattleTerrain.Sand:
                            zrllid = 89;
                            break;
                        case BattleTerrain.Mountain:
                            zrllid = 157;
                            break;
                        case BattleTerrain.Cave:
                            zrllid = 157;
                            break;
                        case BattleTerrain.Water:
                            zrllid = 56;
                            break;
                        default:
                            zrllid = 59;
                            break;
                    }
                    Move zrMove = new Move(zrllid, null, 0);
                    MoveCall(zrMove, user);
                    break;
            }
        }

        private void MoveCall(Move selMove, Pokemon user)
        {
            if (selMove.Data.AddEffect2 == MoveAdditionalEffect.觉醒力量 || selMove.Data.AddEffect2 == MoveAdditionalEffect.制裁飞石 || selMove.Data.AddEffect2 == MoveAdditionalEffect.自然恩惠 || selMove.Data.Effect == MoveEffect.诅咒)
            {
                user.UpdateMove(selMove);
            }
            TargetIndex targetIndex = TargetIndex.DefaultTarget;
            switch (selMove.Target)
            {
                case MoveTarget.选一:
                case MoveTarget.随机:
                    targetIndex = TargetIndex.Random;
                    break;
                case MoveTarget.队友:
                    targetIndex = TargetIndex.TeamFriend;
                    break;
                case MoveTarget.自身:
                case MoveTarget.任选:
                    targetIndex = TargetIndex.Self;
                    break;
            }
            user.LastTarget = targetIndex;
            List<Pokemon> targets = GetTargetsFromIndex(user, selMove, targetIndex);
            UseSkill(user, selMove, targets, true);
        }

        private void Fail()
        {
            log.AppendMsg("Fail0");
            //log.AddText("但它失败了！");
        }

        private void AddLine()
        {
            log.AppendLog(new string('-', 33));
        }

        #endregion
    }
}
